#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
@File   : CloudApi.py
@Time : 2025/1/3 13:53
@Author: Wangwc
@Describe:  云端相关业务方法封装
"""

import os
import subprocess
import time
import requests

from utils.requests_tools import HttpRequest, check_response, retry_func
from utils.login import Login
from commons.logger import log
from utils.config_tools import Config


assert_message = {'code': 200, 'msg': 'success'}
config_name = 'cloud.ini'


class CloudApi:

    #   TODO 默认配置文件需要根据自己的需要更改
    def __init__(self, u_token=None,config_name='cloud.ini'):
        self.config_name = config_name

        self.http = HttpRequest(self.config_name, u_token=u_token)
        self.cloud = Config(self.config_name).read_config_ini('cloud', 'host')

    @check_response('查找局域网设备接口', ext='data.deviceMatchs', check={'code': 200, 'msg': '成功'})
    def get_devices(self):
        """
        获取当前局域网内设备信息
        :return: 当前局域网内设备列表
        """
        log.debug("开始获取当前局域网内设备信息")
        path = "https://api-test1.ugnas.com/api/device/v1/ua/network/match"
        try:
            response = self.http.post(path)
            return response
        except Exception as e:
            log.error(f"在获取当前局域网内设备信息过程中出现异常，异常信息: {e}")
            raise

    def get_device(self, sn, devices: list):
        """
        检查设备是否在线
        :param devices: 当前局域网内设备列表信息
        :return: 返回设备是否在线的布尔值，True表示在线，False表示不在线，若出现异常则根据具体情况记录日志并返回相应结果（可能因异常提前退出而未准确判断设备状态）
        """
        log.info(f"开始检查设备 {sn} 是否在线，传入的设备列表包含 {len(devices)} 个设备")
        try:
            for index, device in enumerate(devices):
                log.debug(f"正在检查第 {index + 1} 个设备，设备信息为: {device}")
                if device.get('deviceSn') == sn:
                    log.info(f"在设备列表中找到设备 {sn}，设备在线")
                    device_info = device
                    return device_info
                else:
                    log.debug(f"第 {index + 1} 个设备 {device.get('deviceSn', '未知设备号')} 不是目标设备 {sn}")
            else:
                log.info(f"遍历完所有设备，未找到设备 {sn}，设备不在线")
                return None
        except Exception as e:
            log.error(f"在检查设备是否在线过程中出现异常，异常信息: {str(e)}，设备列表信息为: {devices}")

    @check_response(ext="data", check=assert_message)
    def get_cloud_owner(self):
        """
        获取云端用户
        :return:
        """
        log.debug("开始执行获取云端用户操作")
        path = f"{self.cloud}/ugreen/v1/user/cloud/owner"
        try:
            response = self.http.get(path)
            return response
        except Exception as e:
            log.error(f"在获取云端用户过程中出现异常，异常信息: {e}")
            raise

    @check_response(ext="data", check=assert_message)
    def identify_country(self):
        """
        确认云端国家节点
        :return:
        """
        log.debug("开始执行确认云端国家节点操作")
        path = f"{self.cloud}/ugreen/v1/verify/identify/country"
        try:
            response = self.http.get(path)
            return response
        except Exception as e:
            log.error(f"在确认云端国家节点过程中出现异常，异常信息: {e}")
            raise

    @check_response(ext="data",check={'code': 200, 'msg': 'SUCCESS'})
    def get_encrypt_key(self):
        """
        获取云端动态密钥
        :return:
        """
        log.debug("开始执行获取云端动态密钥操作")
        path = f"{self.cloud}/api/user/v3/sa/encrypt/key"
        try:
            response = self.http.get(path)
            return response
        except Exception as e:
            log.error(f"在获取云端动态密钥过程中出现异常，异常信息: {e}")
            raise

    @check_response(ext="data",check={'code': 200, 'msg': 'SUCCESS'})
    def get_cloud_token(self, username, password, uuid, platform="PC", clientType="browser", osVer="131.0.0.0",
                        model="Edge/131.0.0.0", bid="83588f6fd862e4de1b237ddc6bba3197", alias="Edge/131.0.0.0"):
        """
        获取云端token（登录）
        :param username: 用户名（加密后） dg7bCC2AmVrZTaSBPa92/w==
        :param password: 密码（加密后） v61pKLn54FnUmD6CmQ1XXw
        :param uuid: uuid 7485434017954d1cb8491b84dfba9608
        :return:
        """
        log.debug("开始执行获取云端token（登录）操作")
        path = f"{self.cloud}/api/oauth/token"
        params = {"platform": platform,
                  "clientType": clientType,
                  "osVer": osVer,
                  "model": model,
                  "bid": bid,
                  "alias": alias,
                  "grant_type": "password",
                  "username": username,
                  "password": password,
                  "uuid": uuid
                  }
        try:
            response = self.http.post(path, params=params)
            return response
        except Exception as e:
            log.error(f"在获取云端token（登录）过程中出现异常，异常信息: {e}")
            raise

    @check_response(ext="data", check=assert_message)
    def get_bind_divices(self):
        """
        根据设备号查询绑定的用户列表
        :return:
        """
        log.debug("开始执行根据设备号查询绑定的用户列表操作")
        path = f"{self.cloud}/api/user/v2/sa/device/userList"
        request_data = {"sn": "UG756JJ02240A6F1", "uuid": "b86e84fd096a4c1a871193a1b0283642", "type": "TRANSFER_VERIFY"}
        try:
            response = self.http.post(path, json=request_data)
            return response
        except Exception as e:
            log.error(f"在根据设备号查询绑定的用户列表过程中出现异常，异常信息: {e}")
            raise

    @check_response(check={'code': 200, 'msg': 'SUCCESS'})
    def send_code(self, accessToken, uuid, codeType=24, sendType=1, sendValue="Np0p7rg6lYHk5GF0flHkaA=="):
        """
        发送获取短信验证码请求
        :param accessToken: 用户token
        :param uuid: 用户唯一标识
        :param codeType: 验证码类型
        :param sendType: 发送类型
        :param sendValue: 值
        :return:
        """
        log.debug("开始执行发送获取短信验证码请求操作")
        path = f"{self.cloud}/api/user/v2/sa/send/code"
        headers = {"Authorization": accessToken}
        request_data = {"sendValue":sendValue,"sendType":sendType,"codeType":codeType,"uuid":uuid}
        try:
            response = self.http.post(path, json=request_data, headers=headers)
            return response
        except Exception as e:
            log.error(f"在发送获取短信验证码请求过程中出现异常，异常信息: {e}")
            raise

    @check_response(check={'code': 200, 'msg': 'SUCCESS'})
    def app_unbind_device(self, accessToken,deviceSn,type="un_bind_user",verifyType="phone",code="666666",clientType="browser"):
        """
        客户端解绑云端账号
        :param accessToken: 用户token
        :param deviceSn: 设备sn
        :param type: 操作类型  1、un_bind_user 解绑
        :param verifyType: 验证类型 transfer_verify 转移验证
        :param code: 验证码
        :param clientType: 客户端类型 browser 浏览器
        :return:
        """
        log.debug("开始执行解绑云端账号操作")
        path = f"{self.cloud}/api/device/app/opt/device/user"
        headers = {"Authorization": accessToken}
        request_data = {"deviceSn": deviceSn, "accessToken": accessToken, "type": type,
                        "verifyType": verifyType, "code": code, "clientType": clientType}
        try:
            response = self.http.post(path, json=request_data,headers=headers)
            return response
        except Exception as e:
            log.error(f"在解绑云端账号过程中出现异常，异常信息: {e}")
            raise

    @check_response(ext="data", check=assert_message)
    def get_user_detail(self):
        """
        获取用户详情（脱敏）
        :return:
        """
        log.debug("开始执行获取用户详情（脱敏）操作")
        path = f"{self.cloud}/api/user/v1/getDetail/hideSenInfo"
        try:
            response = self.http.post(path)
            return response
        except Exception as e:
            log.error(f"在获取用户详情（脱敏）过程中出现异常，异常信息: {e}")
            raise

    @check_response(ext="data", check=assert_message)
    def get_bind_divices(self):
        """
        获取用户绑定设备列表
        :return:
        """
        log.debug("开始执行获取用户绑定设备列表操作")
        path = f"{self.cloud}/api/user/v1/bind/device"
        params = {"versionNo": 123}
        try:
            response = self.http.get(path, params=params)
            return response
        except Exception as e:
            log.error(f"在获取用户绑定设备列表过程中出现异常，异常信息: {e}")
            raise

    @check_response(ext="data", check=assert_message)
    def validate_accountPwd(self):
        """
        获取云端密钥
        :return:
        """
        log.debug("开始执行获取云端密钥操作")
        path = f"{self.cloud}/api/user/v2/sa/validate/accountPwd"
        request_data = {"account": "5QbqKHfkDNw2OGBlIL9vGA==", "pwd": "DJfB9zlwEs1FoFZ0wKNWpw==",
                        "uuid": "3a62b20063d1432aa3007569c0be6737"}
        try:
            response = self.http.post(path, json=request_data)
            return response
        except Exception as e:
            log.error(f"在获取云端密钥过程中出现异常，异常信息: {e}")
            raise

    @check_response(ext="data", check=assert_message)
    def uglink_heartbeat(self, internalDomain):
        """
        设备心跳检查
        :param internalDomain:uglink status接口返回，从data.internalDomain 提取
        :return:
        """
        log.debug("开始执行设备心跳检查操作")
        path = f"https://{internalDomain}/ugreen/v1/verify/heartbeat"
        try:
            response = self.http.get(path)
            return response
        except Exception as e:
            log.error(f"在设备心跳检查过程中出现异常，异常信息: {e}")
            raise

    # @check_response(ext="data", check=assert_message)
    # def get_uglink_nodeInfo_byAlias(self, alias):
    #     """
    #     根据uglink id 获取节点信息
    #     :param alias:uglink id  示例：wang1234
    #     :return:
    #     """
    #     log.debug("开始执行根据uglink id 获取节点信息操作")
    #     path = "/api/p2p/v2/ta/nodeInfo/byAlias"
    #     request_data = {"alias": alias}
    #     try:
    #         response = self.http.post(path, json=request_data)
    #         return response
    #     except Exception as e:
    #         log.error(f"在根据uglink id 获取节点信息过程中出现异常，异常信息: {e}")
    #         raise

    @check_response(ext="data", check=assert_message)
    def uglink_verify_check(self, internalDomain, username):
        """
        uglink url 获取access_token
        :param: internalDomain:uglink status接口返回，从data.internalDomain 提取
        :return:
        """
        log.debug("开始执行uglink 获取access_token操作")
        path = f"https://{internalDomain}/ugreen/v1/verify/check"
        params = {"token": ""}
        request_data = {"username": username}
        try:
            response = self.http.post(path, json=request_data, params=params)
            return response
        except Exception as e:
            log.error(f"在获取云端密钥过程中出现异常，异常信息: {e}")
            raise

    @check_response(ext="data", check=assert_message)
    def uglink_login(self, internalDomain, username, raw_passwd):
        """
        uglink url登录
        :param: internalDomain:uglink status接口返回，从data.internalDomain 提取
        :return:
        """
        log.debug("开始执行uglink链接登录操作")
        path = f"https://{internalDomain}/ugreen/v1/verify/login"
        passwd = raw_passwd
        request_data = {"username": username,
                        "password": passwd,
                        "otp": True, "is_simple": True}
        try:
            response = self.http.post(path, json=request_data)
            return response
        except Exception as e:
            log.error(f"在uglink链接登录过程中出现异常，异常信息: {e}")
            raise

    @check_response(ext="data", check=assert_message)
    def verify_check(self, lan, port=9443):
        """
        uglink 获取access_token
        :param: lan:云端节点返回的lan，从data.netInfo.smartdns.lan 提取
        :param: port:云端节点返回的port，从data.netInfo.httpsPort 提取
        :return:
        """
        log.debug("开始执行获取云端密钥操作")
        path = f"https://{lan}:{port}/ugreen/v1/verify/check"
        params = {"token": ""}
        request_data = {"username": "test3"}
        try:
            response = self.http.post(path, json=request_data, params=params)
            return response
        except Exception as e:
            log.error(f"在获取云端密钥过程中出现异常，异常信息: {e}")
            raise

    @check_response(ext="data", check=assert_message)
    def login(self, lan, username, raw_passwd, port=9443):
        """
        uglink登录
        :param: lan:云端节点返回的lan，从data.netInfo.smartdns.lan 提取
        :param: port:云端节点返回的port，从data.netInfo.httpsPort 提取
        :return:
        """
        log.debug("开始执行uglink登录操作")
        path = f"https://{lan}:{port}/ugreen/v1/verify/login"
        passwd = raw_passwd
        request_data = {"username": username,
                        "password": passwd,
                        "otp": True, "is_simple": True}
        try:
            response = self.http.post(path, json=request_data)
            return response
        except Exception as e:
            log.error(f"在uglink登录过程中出现异常，异常信息: {e}")
            raise

    @check_response(ext="data", check=assert_message)
    def system_check(self):
        """
        uglink检查
        :return:
        """
        log.debug("开始执行uglink登录操作")
        path = "https://172-17-20-57.wang1234.direct-test.ug.link:9443/system/check"
        try:
            response = self.http.get(path)
            return response
        except Exception as e:
            log.error(f"在uglink检查过程中出现异常，异常信息: {e}")
            raise


if __name__ == "__main__":
    a = CloudApi()
    devices = a.get_devices()
    sn = Config(config_name).read_config_ini("device", "device_sn")
    device = a.get_device(sn, devices)
    print(device)
